package team6.ai;

import team6.*;
import team6.gamegui.GameState;
import team6.gametree.*;
/**
 * @author Drew Havard
 * @author Drew Reagan
 * 
 * A variable difficulty AI that bases it's decisions entirely on
 * 
 * @param depthOfSearch	int: depth to build the tree to.  Suggested to be not more than 5
 * @param gameTree		UtilityTree: The tree which is rebuild for each decision of the AI
 * @param CONSTANTS		double[]:  Constants for the utilityFunction
 * 						Format is: 1st constant is value of pieces
 * 						2nd constant is value of opponent moves (usually negative)
 * 						3rd constant is value of corners
 * 						Constants for this ai: {20, -3, 300}
 *
 */
public class MinMax extends AI{
	/**
	 * Depth to build the tree to.  Suggested to be not more than 5.
	 */
	int depthOfSearch;
	/**
	 * The tree which is rebuild for each decision of the AI.
	 */
	UtilityTree gameTree;
	/**
	 * Constants for the utilityFunction
	 * Format is: 1st constant is value of pieces
 	 * 2nd constant is value of opponent moves (usually negative)
 	 * 3rd constant is value of corners
 	 * Constants for this ai: {20, -3, 300}
	 */
	final double[] CONSTANTS = {20.0, -3.0, 300.0};
	
	
	/**
	 * Initializes the AI based on the given difficulty.  This AI will be the color given by the
	 * player parameter.  Difficulty is determined by the depth the tree is built to.
	 * @param player The color the AI will be set to.
	 * @param difficulty The AI.Difficulty that this AI is set to, which controls the depth of tree
	 * @throws IllegalArgumentException	Player can't be empty
	 */
	public MinMax(Player player, Difficulty difficulty)
			throws IllegalArgumentException {
		super(player, difficulty);
		if(difficulty == Difficulty.EASY){
			depthOfSearch = 1;
			gameTree = new UtilityTree(depthOfSearch, CONSTANTS);
		}else if(difficulty == Difficulty.MEDIUM){
			depthOfSearch = 3;
			gameTree = new UtilityTree(depthOfSearch, CONSTANTS);
		}else if(difficulty == Difficulty.HARD){
			depthOfSearch = 5;
			gameTree = new UtilityTree(depthOfSearch, CONSTANTS);
		}
		// TODO Auto-generated constructor stub
	}

	/**
	 * Use the utility tree to decide the best move.
	 * Will construct tree, and whichever move is best is returned
	 * Will return null if no available moves.
	 * Calls state.setPlayer to make sure the correct player's turn is chosen
	 * @param boardState The current state to pick a move on
	 * @param lastMove The last move for the given board
	 * @return Returns the best move for gameTree in {row, column} form
	 */
	public int[] makeMove(Player[][] boardState, int[] lastMove) {
		GameState state = new GameState(boardState, lastMove);
		state.setPlayer(lastMove);
		gameTree.buildTree(state);
		int [] move = gameTree.bestMove();
		return move;
	}
	

}
